package com.example.rabbitmq.starter.controller;

import com.example.rabbitmq.starter.entity.FailedMessageInfo;
import com.example.rabbitmq.starter.exception.ApiResponse;
import com.example.rabbitmq.starter.exception.BusinessException;
import com.example.rabbitmq.starter.exception.ResourceNotFoundException;
import com.example.rabbitmq.starter.service.FailedMessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;

/**
 * 失败消息管理控制器
 *
 * @author example
 * @since 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/api/rabbitmq/failedMessage")
@RequiredArgsConstructor
public class FailedMessageController {

    private final FailedMessageService failedMessageService;

    /**
     * 分页查询失败消息
     *
     * @param page        页码，从0开始
     * @param size        每页大小
     * @param messageType 消息类型（可选）
     * @param status      状态（可选）
     * @param sort        排序字段，默认按创建时间倒序
     * @return 分页结果
     */
    @GetMapping("/page")
    public ApiResponse<Page<FailedMessageInfo>> getFailedMessages(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) String messageType,
            @RequestParam(required = false) String status,
            @RequestParam(defaultValue = "createTime") String sort) {

        // 创建分页和排序对象
        Sort sortObj = Sort.by(Sort.Direction.DESC, sort);
        Pageable pageable = PageRequest.of(page, size, sortObj);

        // 根据条件查询
        Page<FailedMessageInfo> result;
        if (messageType != null && status != null) {
            result = failedMessageService.findByMessageTypeAndStatus(messageType, status, pageable);
        }
        else if (messageType != null) {
            result = failedMessageService.findByMessageType(messageType, pageable);
        }
        else if (status != null) {
            result = failedMessageService.findByStatus(status, pageable);
        }
        else {
            result = failedMessageService.findAll(pageable);
        }

        return ApiResponse.success("查询成功", result);
    }

    /**
     * 查询失败消息列表（不分页）
     *
     * @param messageType 消息类型（可选）
     * @param status      状态（可选）
     * @return 失败消息列表
     */
    @GetMapping("/list")
    public ApiResponse<List<FailedMessageInfo>> getFailedMessagesList(
            @RequestParam(required = false) String messageType,
            @RequestParam(required = false) String status) {

        List<FailedMessageInfo> result;
        if (messageType != null && status != null) {
            result = failedMessageService.findByMessageTypeAndStatus(messageType, status);
        }
        else if (messageType != null) {
            result = failedMessageService.findByMessageType(messageType);
        }
        else if (status != null) {
            result = failedMessageService.findByStatus(status);
        }
        else {
            result = failedMessageService.findAll();
        }

        return ApiResponse.success("查询成功", result);
    }

    /**
     * 根据ID获取失败消息详情
     *
     * @param id 失败消息ID
     * @return 失败消息详情
     */
    @GetMapping("/get")
    public ApiResponse<FailedMessageInfo> getFailedMessageById(@RequestParam String id) {
        FailedMessageInfo messageInfo = failedMessageService.getFailedMessageById(id);
        if (messageInfo == null) {
            throw new ResourceNotFoundException("失败消息");
        }
        return ApiResponse.success("查询成功", messageInfo);
    }

    /**
     * 重试失败消息
     *
     * @param id 失败消息ID
     * @return 重试结果
     */
    @PostMapping("/retry")
    public ApiResponse<String> retryFailedMessage(@RequestParam String id) {
        boolean result = failedMessageService.retryMessage(id);
        if (!result) {
            throw new BusinessException("消息重试操作失败，请检查消息状态");
        }
        return ApiResponse.success("重试成功");
    }

    /**
     * 批量重试失败消息
     *
     * @param ids 失败消息ID列表
     * @return 重试结果
     */
    @PostMapping("/batch-retry")
    public ApiResponse<Map<String, Object>> retryFailedMessages(@RequestBody @Valid List<String> ids) {
        int successCount = failedMessageService.retryFailedMessages(ids);
        Map<String, Object> result = new HashMap<>();
        result.put("total", ids.size());
        result.put("successCount", successCount);
        result.put("failCount", ids.size() - successCount);
        return ApiResponse.success("批量重试完成", result);
    }

    /**
     * 重试所有失败消息
     *
     * @return 重试结果
     */
    @PostMapping("/retry-all")
    public ApiResponse<Map<String, Object>> retryAllFailedMessages() {
        int successCount = failedMessageService.retryAllFailedMessages();
        Map<String, Object> result = new HashMap<>();
        result.put("successCount", successCount);
        return ApiResponse.success("全部重试完成", result);
    }

    /**
     * 忽略失败消息
     *
     * @param id     失败消息ID
     * @param reason 忽略原因
     * @return 操作结果
     */
    @PostMapping("/ignore")
    public ApiResponse<String> ignoreFailedMessage(
            @RequestParam String id,
            @RequestParam(required = false, defaultValue = "手动忽略") String reason) {
        boolean result = failedMessageService.ignoreMessage(id, reason);
        if (!result) {
            throw new BusinessException("消息忽略操作失败，请检查消息状态");
        }
        return ApiResponse.success("忽略成功");
    }

    /**
     * 批量忽略失败消息
     *
     * @param request 请求体，包含消息ID列表和忽略原因
     * @return 操作结果
     */
    @PostMapping("/batch-ignore")
    public ApiResponse<Map<String, Object>> ignoreFailedMessages(@RequestBody @Valid Map<String, Object> request) {
        @SuppressWarnings("unchecked")
        List<String> ids = (List<String>) request.get("ids");
        String reason = request.get("reason") != null ? request.get("reason").toString() : "批量忽略";

        int successCount = failedMessageService.ignoreFailedMessages(ids, reason);
        Map<String, Object> result = new HashMap<>();
        result.put("total", ids.size());
        result.put("successCount", successCount);
        result.put("failCount", ids.size() - successCount);
        return ApiResponse.success("批量忽略完成", result);
    }

    /**
     * 删除失败消息
     *
     * @param id 失败消息ID
     * @return 操作结果
     */
    @PostMapping("/delete")
    public ApiResponse<String> deleteFailedMessage(@RequestParam String id) {
        boolean result = failedMessageService.deleteMessage(id);
        if (!result) {
            throw new BusinessException("消息删除操作失败，请检查消息状态");
        }
        return ApiResponse.success("删除成功");
    }

    /**
     * 批量删除失败消息
     *
     * @param ids 失败消息ID列表
     * @return 操作结果
     */
    @PostMapping("/batch-delete")
    public ApiResponse<Map<String, Object>> deleteFailedMessages(@RequestBody @Valid List<String> ids) {
        int successCount = failedMessageService.deleteFailedMessages(ids);
        Map<String, Object> result = new HashMap<>();
        result.put("total", ids.size());
        result.put("successCount", successCount);
        result.put("failCount", ids.size() - successCount);
        return ApiResponse.success("批量删除完成", result);
    }

    /**
     * 保存失败消息
     *
     * @param messageInfo 失败消息信息
     * @return 保存结果
     */
    @PostMapping("/save")
    public ApiResponse<FailedMessageInfo> saveFailedMessage(@RequestBody @Valid FailedMessageInfo messageInfo) {
        FailedMessageInfo saved = failedMessageService.saveFailedMessage(messageInfo);
        return ApiResponse.success("保存成功", saved);
    }
}